package com.kuaishou.test.plugin;

import static com.kuaishou.framework.util.ObjectMapperUtils.toJSON;
import static com.kuaishou.test.model.ResultCode.SERVICE_BUSY;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.kuaishou.test.model.Message;

/**
 * Spring 全局异常处理器
 *
 * Write the code. Change the world.
 *
 * @author trang
 */
@RestControllerAdvice
public class ExceptionHandlers {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlers.class);

    @ExceptionHandler(Throwable.class)
    public Message<?> handleThrowable(HttpServletRequest request, Throwable e) {
        printStackTrace(request, e);
        Throwable rootCause = Throwables.getRootCause(e);
        return Message.error(SERVICE_BUSY, rootCause);
    }

    /**
     * 打印异常信息
     */
    private void printErrorMsg(Throwable e) {
        logger.error("handle:{}, msg:{}", e.getClass().getName(), e.getMessage());
    }

    /**
     * 打印异常信息和入参
     */
    private void printErrorMsg(HttpServletRequest request, Throwable e) {
        Map<String, String[]> params = request.getParameterMap();
        Map<String, Object> map = Maps.transformValues(
                params, arr -> (arr == null || arr.length == 0) ? null : arr.length == 1 ? arr[0] : arr
        );
        logger.error("handle:{}, msg:{}, params:{}", e.getClass().getName(), e.getMessage(), toJSON(map));
    }

    /**
     * 打印异常堆栈和入参
     */
    private void printStackTrace(HttpServletRequest request, Throwable e) {
        Map<String, String[]> params = request.getParameterMap();
        Map<String, Object> map = Maps.transformValues(
                params, arr -> (arr == null || arr.length == 0) ? null : arr.length == 1 ? arr[0] : arr
        );
        logger.error("handle:{},  msg: {}, params:{}", e.getClass().getName(), e.getMessage(), toJSON(map), e);
    }

}
